# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
# $Id: Portfile 140329 2015-09-17 10:21:12Z ryandesign@macports.org $

PortSystem      1.0
PortGroup       compiler_blacklist_versions 1.0
PortGroup       mpi 1.0

name            boost
version         1.59.0
revision        1
license         Boost-1
categories      devel
platforms       darwin
maintainers     ryandesign openmaintainer

description     Collection of portable C++ source libraries

long_description \
    Boost provides free portable peer-reviewed C++ \
    libraries. The emphasis is on portable libraries \
    which work well with the C++ Standard Library.

homepage        http://www.boost.org
master_sites    sourceforge:project/boost/boost/${version}
set distver     [join [split ${version} .] _]
distname        ${name}_${distver}
use_bzip2       yes

checksums       rmd160  a106b3cd1dbda2323e5e84c7106cedee327db03c \
                sha256  727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca

depends_lib     port:zlib \
                port:expat \
                port:bzip2 \
                port:libiconv \
                port:icu

post-extract {
    fs-traverse dir ${workpath} {
        if [file isdirectory ${dir}] {
            file attributes ${dir} -permissions a+rx
        }
    }
}

patchfiles      patch-tools-build-src-engine-build.sh.diff \
                patch-tools-build-src-engine-build.jam.diff \
                patch-apple-clang-no-libcxx.diff \
                patch-log-setup-link.diff
                # patch-apple-clang-no-libcxx.diff fixes a clang configuration
                # error that occurs on OS X 10.7 and 10.8 due to the assumption
                # that if clang is the compiler in use it must be using libc++.
                # Apple Clang uses libstdc++ by default on these OS versions.
                # The patch adds an additional BOOST_* configuration flag
                # that is set if Apple clang is being used but libc++
                # is not.  This flag is then used to prevent boost or a
                # dependent package from using functions such as std::forward that
                # are only available in libc++.  Fixes build of libcdr on these
                # OS versions without affecting build on 10.6 and less (where clang is not
                # the default compiler) or 10.9 and up (where libc++ is the default).

post-patch {
    reinplace "s|%%CONFIGURE.CC%%|${configure.cc}|g" ${worksrcpath}/tools/build/src/engine/build.jam \
                                                     ${worksrcpath}/tools/build/src/engine/build.sh
}

proc write_jam s {
    global worksrcpath
    set config [open ${worksrcpath}/user-config.jam a]
    puts ${config} ${s}
    close ${config}
}

# clang++ produces broken boost libraries (https://trac.macports.org/ticket/31525)
# If Apple's clang is used on 32-bit systems, it seems to silently ignore the '-march=i386' flag.
# (https://trac.macports.org/ticket/38157)
compiler.blacklist {clang < 421} macports-clang-2.9 macports-clang-3.0 *llvm-gcc-4.2 *gcc-4.0 gcc-3.3

compilers.choose   cc cxx
mpi.setup          -gcc -dragonegg

# It turns out that ccache and distcc can produce boost libraries that, although they
# compile without warning, have all sorts of runtime errors especially with pointer corruption.
# Since most people will now use MacPorts' pre-compiled boost, this should not be a problem.
configure.ccache    no
configure.distcc    no

configure.cmd       ./bootstrap.sh
configure.args      --without-libraries=python \
                    --without-libraries=mpi \
                    --with-icu=${prefix}

if {${os.platform} eq "darwin" && ${os.major} <= 10} {
    configure.args-append   --without-libraries=context \
                            --without-libraries=coroutine
}

configure.universal_args

post-configure {

    reinplace -E "s|-install_name \"|&${prefix}/lib/|" \
        ${worksrcpath}/tools/build/src/tools/darwin.jam

    set compileflags ""
    if {[string length ${configure.sdkroot}] != 0} {
        set compileflags "<compileflags>\"-isysroot ${configure.sdkroot}\""
    }

    set cxx_stdlibflags {}
    if {[string match *clang* ${configure.cxx}]} {
        set cxx_stdlibflags -stdlib=${configure.cxx_stdlib}
    }

    write_jam "using darwin : : ${configure.cxx} : <cxxflags>\"${configure.cxxflags} ${cxx_stdlibflags}\" ${compileflags} <linkflags>\"${configure.ldflags} ${cxx_stdlibflags}\" : ;"

}

build.cmd       ${worksrcpath}/b2
build.target
build.args      -d2 \
                --layout=tagged \
                --debug-configuration \
                --user-config=user-config.jam \
                -sBZIP2_INCLUDE=${prefix}/include \
                -sBZIP2_LIBPATH=${prefix}/lib \
                -sEXPAT_INCLUDE=${prefix}/include \
                -sEXPAT_LIBPATH=${prefix}/lib \
                -sZLIB_INCLUDE=${prefix}/include \
                -sZLIB_LIBPATH=${prefix}/lib \
                -sICU_PATH=${prefix} \
                variant=release \
                threading=single,multi \
                link=static,shared \
                -j${build.jobs}

destroot.cmd            ${worksrcpath}/bjam
destroot.post_args

pre-destroot {
    destroot.args {*}${build.args} --prefix=${destroot}${prefix}
    system "find ${worksrcpath} -type f -name '*.gch' -exec rm {} \\;"
}

post-destroot {
    set docdir ${prefix}/share/doc/${name}
    xinstall -d ${destroot}${docdir}
    set l [expr [string length ${worksrcpath}] + 1]
    fs-traverse f [glob -directory ${worksrcpath} *] {
        set dest ${destroot}${docdir}/[string range ${f} ${l} end]
        if {[file isdirectory ${f}]} {
            if {[file tail ${f}] eq "example"} {
                copy ${f} ${dest}
                continue
            }
            xinstall -d ${dest}
        } elseif {[lsearch -exact {css htm html png svg} [string range [file extension ${f}] 1 end]] != -1} {
            xinstall -m 644 ${f} ${dest}
        }
    }
}

# TODO: Remove after 2016-05-26.
variant python25 description {Legacy variant} requires python27 {}
variant python31 description {Legacy variant} requires python34 {}
variant python32 description {Legacy variant} requires python34 {}

set pythons_suffixes {26 27 33 34 35}

set pythons_ports {}
foreach s ${pythons_suffixes} {
    lappend pythons_ports python${s}
}

proc python_dir {} {
    global pythons_suffixes
    foreach s ${pythons_suffixes} {
        if {[variant_isset python${s}]} {
            set p python[string index ${s} 0].[string index ${s} 1]
            return [file normalize [exec ${p} -c "import sys; print(sys.prefix)"]/lib/${p}/site-packages]
        }
    }
    error "Python support not enabled."
}

foreach s ${pythons_suffixes} {
    set p python${s}
    set v [string index ${s} 0].[string index ${s} 1]
    set i [lsearch -exact ${pythons_ports} ${p}]
    set c [lreplace ${pythons_ports} ${i} ${i}]
    if { ${s} > 30 } { set bppatch "patch-boost-python3.diff" } else { set bppatch "" }
    eval [subst {
        variant ${p} description "Build Boost.Python for Python ${v}" conflicts ${c} debug {

            # There is a conflict with python and debug support, so we should really change the 'variant' line above
            # to end with "conflicts ${c} debug" above. However, we leave it enabled for those who want to try it.
            # The issue has been reported to both the MacPorts team and the boost team, as per:
            # <http://trac.macports.org/ticket/23667> and <https://svn.boost.org/trac/boost/ticket/4461>

            depends_lib-append      port:${p}
            configure.args-delete   --without-libraries=python
            configure.args-append   --with-python=${prefix}/bin/python${v} --with-python-root=${prefix}/bin/python${v}

            patchfiles-append   ${bppatch} patch-tools-build-src-tools-python.jam.diff \
                                patch-tools-build-src-tools-python-2.jam.diff

            post-patch {
                reinplace s|@FRAMEWORKS_DIR@|${frameworks_dir}| ${worksrcpath}/tools/build/src/tools/python.jam
            }

        }
    }]
}

if {![variant_isset debug]} {
    set selected_python python27
    foreach s ${pythons_suffixes} {
        if {[variant_isset python${s}]} {
            set selected_python python${s}
        }
    }
    default_variants +${selected_python}
}

default_variants +no_single +no_static

variant debug description {Builds debug versions of the libraries as well} {
    build.args-delete   variant=release
    build.args-append   variant=debug,release
}

variant no_static description {Disable building static libraries} {
    build.args-delete   link=static,shared
    build.args-append   link=shared
}

variant no_single description {Disable building single-threaded libraries} {
    build.args-delete   threading=single,multi
    build.args-append   threading=multi
}

variant regex_match_extra description \
        "Enable access to extended capture information of submatches in Boost.Regex" {
    notes-append "
You enabled the +regex_match_extra variant\; see the following page for an\
exhaustive list of the consequences of this feature:

http://www.boost.org/doc/libs/${distver}/libs/regex/doc/html/boost_regex/ref/sub_match.html
"

    post-patch {
        reinplace {/#define BOOST_REGEX_MATCH_EXTRA/s:^// ::} \
            ${worksrcpath}/boost/regex/user.hpp
    }
}

if {[mpi_variant_isset]} {

    # There is a conflict with debug support.
    # The issue has been reported to both the MacPorts team and the boost team, as per:
    # <http://trac.macports.org/ticket/23667> and <https://svn.boost.org/trac/boost/ticket/4461>
    if {[variant_isset debug]} {
        return -code error "+debug variant conflicts with mpi"
    }

    configure.args-delete   --without-libraries=mpi

    post-configure {
        write_jam "using mpi : ${mpi.cxx} : : ${mpi.exec} ;"
    }

    if {![catch python_dir]} {

        patchfiles-append patch-libs-mpi-build-Jamfile.v2.diff

        post-destroot {
            set site_packages [python_dir]
            xinstall -d ${destroot}${site_packages}/boost
            xinstall -m 644 ${worksrcpath}/libs/mpi/build/__init__.py \
                ${destroot}${site_packages}/boost

            set l ${site_packages}/boost/mpi.so
            move ${destroot}${prefix}/lib/mpi.so ${destroot}${l}
            system "install_name_tool -id ${l} ${destroot}${l}"
        }

    }
}

if {![variant_isset universal]} {
    # Honour 'build_arch', if not universal as per #28327
    if {[lsearch ${build_arch} ppc*] != -1} {
        build.args-append   architecture=power
        if {${os.arch} ne "powerpc"} {
            build.args-append   --disable-long-double
        }
    } else {
        if {[lsearch ${build_arch} *86*] != -1} {
            build.args-append   architecture=x86
        } else {
            pre-fetch {
                error "Current value of 'build_arch' is not supported."
            }
        }
    }
    if {[lsearch ${build_arch} *64] != -1} {
        build.args-append   address-model=64
    } else {
        build.args-append   address-model=32
    }
}

variant universal {
    build.args-append   pch=off

    if {[lsearch ${universal_archs} ppc*] != -1} {
        if {[lsearch ${universal_archs} *86*] != -1} {
            build.args-append   architecture=combined
        } else {
            build.args-append   architecture=power
        }

        if {${os.arch} ne "powerpc"} {
            build.args-append   --disable-long-double
        }
    } else {
        build.args-append   architecture=x86
    }

    if {[lsearch ${universal_archs} *64] != -1} {
        if {[lsearch ${universal_archs} i386] != -1 || [lsearch ${universal_archs} ppc] != -1} {
            build.args-append   address-model=32_64
            if {[lsearch ${universal_archs} ppc64] == -1} {
                post-patch {
                    reinplace "/local support-ppc64 =/s/= 1/= /" ${worksrcpath}/tools/build/src/tools/darwin.jam
                }
            }
        } else {
            build.args-append   address-model=64
        }
    } else {
        build.args-append   address-model=32
    }
}

platform powerpc {
    build.args-append   --disable-long-double
}

platform darwin 8 powerpc {
    if {[variant_isset universal]} {
        build.args-append   macosx-version=10.4
    }
}

livecheck.type  regex
livecheck.url   ${homepage}
livecheck.regex ${name}/(\\d+\\.\\d+\\.\\d+)/
